package com.springboot.config.redis.cluster;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.springboot.config.redis.ICacheService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.google.common.collect.Lists;

import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.Tuple;

@Component
public class CacheClusterService implements ICacheService {

	@Autowired
	private JedisCluster jedis;
	
	/**
	 * 
	 * set(key,string)
	 * @param key
	 * @param value
	 * @throws Exception
	 * void
	 * @exception
	 * @since  1.0.0
	 */
	public String set(String key, String value){
		return jedis.set(key, value);
	}
	
	/**
	 * 
	 * get(返回指定key值)
	 * @param key
	 * @return
	 * String
	 * @exception
	 * @since  1.0.0
	 */
	public String get(String key){
		String value = null;
		try{
			value = jedis.get(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 
	 * get(返回指定key值)
	 * @param key
	 * @return
	 * String
	 * @exception
	 * @since  1.0.0
	 */
	public List<String> mget(String...params){
		 List<String> values = null;
		try{
			values = jedis.mget(params);
		}catch(Exception e){
			e.printStackTrace();
		}
		return values;
	}
	
	/**
	 * 判断是否有某个key
	 * @param key
	 * @return
	 * String
	 * @exception
	 * @since  1.0.0
	 */
	public boolean exists(String key){
		try{
			return jedis.exists(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return false;
	}

	/**
	 * 
	 * push(在指定链表头部增加一个或多个值，链表不存在则新建)
	 * @param queueName 队列名
	 * @param values 值顺序列表，如：a,b,c.先进先出
	 * @return Long 队列元素个数
	 * @exception
	 * @since  1.0.0
	 */
	public Long push(String queueName,String... values){
		Long queueLength = 0L;
		try{
			queueLength = jedis.lpush(queueName, values);
		}catch(Exception e){
			e.printStackTrace();
		}
		return queueLength;
	}
	
	/**
	 * 
	 * pop(从指定队列表尾部取出一个值)
	 * @param queueName 队列名
	 * @return String 元素值
	 * @exception
	 * @since  1.0.0
	 */
	public String pop(String queueName){
		String value = null;
		try{
			value =jedis.rpop(queueName);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * 
	 * lrange(从指定队列取起始位置到结束位置元素)
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 * List<String>
	 * @exception
	 * @since  1.0.0
	 */
	public List<String> lrange(String key,long start, long end){
		List<String>  value = Lists.newArrayList();;
		try{
			value = jedis.lrange(key, start, end);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	/**
	 * lrange(从指定队列取起始位置到结束位置元素)
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 * List<String>
	 * @exception
	 * @since  1.0.0
	 */
	public long llen(String key){
		long value = 0L;
		try{
			value = jedis.llen(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	public Long hset(String key,String field, String value){
		try{
			return jedis.hset(key, field, value);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public void hmset(String key, Map<String,String> value){
		try{
			jedis = getJedisCluster();
			jedis.hmset(key, value);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	public String hget(String key,String field){
		String value = null;
		try{
			jedis = getJedisCluster();
			value = jedis.hget(key, field);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	public Map<String,String> hget(String key){
		Map<String,String> value = null;
		
		try{
			jedis = getJedisCluster();
			 value = jedis.hgetAll(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}
	
	public List<String> hmget(String key,String...fields){
		List<String> value = null;
		try{
			jedis = getJedisCluster();
			value = jedis.hmget(key, fields);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	} 
	
	public Long hdel(String key,String...fields){
		Long value = null;
		try{
			jedis = getJedisCluster();
			 value = jedis.hdel(key, fields);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	} 
	
	/**
	 * 
	 * queueLength(返回指定队列元素个数)
	 * @param queueName
	 * @return Long
	 * @exception
	 * @since  1.0.0
	 */
	public Long queueLength(String queueName){
		Long queueLength = 0L;
		
		try{
			jedis = getJedisCluster();
			queueLength = jedis.llen(queueName);
		}catch(Exception e){
			e.printStackTrace();
		}
		return queueLength;
	}
	
	/**
	 * 
	 * zcard(返回key Sets数量)
	 * @param key
	 * @return
	 * Long
	 * @exception
	 * @since  1.0.0
	 */
	public Long zcard(String key){
		Long c = 0L;
		try{
			jedis = getJedisCluster();
			c = jedis.zcard(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return c;
	}
	
	/**
	 * 
	 * zrange(返回有序list，以score正序排，1，2，3，4等 )
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 * List<String>
	 * @exception
	 * @since  1.0.0
	 */
	public Set<String> zrange(String key,final long start,final long end){
		try{
			jedis = getJedisCluster();
			return jedis.zrange(key, start, end);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	public List<String> zrevrange(String key,final int start, final int end){
		LinkedHashSet<String> set = new LinkedHashSet<String>();
		
		try{
			jedis = getJedisCluster();
			set = (LinkedHashSet<String>)jedis.zrevrange(key, start, end);
		}catch(Exception e){
			e.printStackTrace();
		}
		return  new ArrayList<String>(set);
	}
	
	public List<Tuple> zrangeWithScores(String key,final long start,final long end){
		LinkedHashSet<Tuple> set = new LinkedHashSet<Tuple>();
		
		try{
			jedis = getJedisCluster();
			jedis.zrangeWithScores(key, start, end);
			set = (LinkedHashSet<Tuple>)jedis.zrangeWithScores(key, start, end);
		}catch(Exception e){
			e.printStackTrace();
		}
		return  new ArrayList<Tuple>(set);
	}
	
	
	/**
	 * 
	 * zrevrangeByScore(返回有续集key中score<=max并且score>=min 的元素，返回结果根据score从大到小顺序排列 )
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 * List<String>
	 * @exception
	 * @since  1.0.0
	 */
	public List<String> zrevrangeByScore(String key,final double min,final double max, int skip, int size){
		LinkedHashSet<String> set = new LinkedHashSet<String>();
		
		try{
			jedis = getJedisCluster();
			set = (LinkedHashSet<String>)jedis.zrevrangeByScore(key, max, min, skip, size);
		}catch(Exception e){
			e.printStackTrace();
		}
		return  new ArrayList<String>(set);
	}

	
	public void zrem(String key,String... members){
		
		try{
			jedis = getJedisCluster();
			jedis.zrem(key, members);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	/**
	 * 
	 * zscore(返回某个成员的分数，如果不存在返回null)
	 * @param key
	 * @param member
	 * @return
	 * Double
	 * @exception
	 * @since  1.0.0
	 */
	public Double zscore(String key,String member){
		
		try{
			jedis = getJedisCluster();
			Double v = jedis.zscore(key, member);
			return v;
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * incr(按key自增(+1))
	 * @param key
	 * @return
	 * Long
	 * @exception
	 * @since  1.0.0
	 */
	public Long incr(String key){
		Long i = null;
		
		try{
			jedis = getJedisCluster();
			i = jedis.incr(key);
		}catch(Exception e){
			e.printStackTrace();
		}
		return i;
	}
	
	public Long incrBy(String key, long increament){
		Long i = null;
		
		try{
			jedis = getJedisCluster();
			i = jedis.incrBy(key, increament);
		}catch(Exception e){
			e.printStackTrace();
		}
		return i;
	}
	
	/**
	 * redis锁
	 * @param key
	 * @param value
	 * @return
	 */
	public Long setnx(String key,String value){
		Long i = null;
		
		try{
			jedis = getJedisCluster();
			i = jedis.setnx(key, value);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//jedis.close();
		}
		return i;
	}
	
	public JedisCluster getJedisCluster(){
		return jedis;
	}

	/**
	 * SET 集合
	 * 判断成员元素是否是集合的成员
	 * @param key
	 * @param member
	 * @return
	 */
	public Boolean sismember(String key, String member) {
		Boolean sismember = null;
		
		try{
			jedis = getJedisCluster();
			sismember = jedis.sismember(key, member);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//jedis.close();
		}
		return sismember;
	}

	/**
	 * SET 集合
	 * 移除集合中的一个元素，不存在会被忽略
	 * @param key
	 * @param member
	 * @return
	 */
	public Long srem(String key, String member) {
		Long sismember = null;
		
		try{
			jedis = getJedisCluster();
			sismember = jedis.srem(key, member);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//jedis.close();
		}
		return sismember;
	}
	
	/**
	 * SET 集合
	 * 移除集合中的一个或多个成员元素，不存在的成员元素会被忽略
	 * @param key
	 * @param members
	 * @return
	 */
	public Long srem(String key, String[] members) {
		Long srem = null;
		
		try{
			jedis = getJedisCluster();
			srem = jedis.srem(key, members);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//jedis.close();
		}
		return srem;
	}
	
	/**
	 * SET 有序集合
	 * 移除集合中的一个元素，不存在会被忽略
	 * @param key
	 * @param member
	 * @return
	 */
	public Long zrem(String key, String member) {
		Long sismember = null;
		
		try{
			jedis = getJedisCluster();
			sismember = jedis.zrem(key, member);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			//jedis.close();
		}
		return sismember;
	}

	
	/**
	 * SET 有序集合
	 * 返回有序集中指定成员的排名
	 * @param key
	 * @param member
	 * @return
	 */
	public Long zrank(String key, String member) {
		Long index = null;
		
		try{
			jedis = getJedisCluster();
			index = jedis.zrank(key, member);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
				//jedis.close();
		}
		return index;
	}

	@Override
	public String setex(String key, int seconds, String value) {
		try{
			return jedis.setex(key, seconds, value);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Set<String> keys(String key) {
		return jedis.hkeys(key);
	}

	@Override
	public long dels(String... keys) {
		try{
			return jedis.del(keys);
		}catch(Exception e){
			e.printStackTrace();
		}
		return 0;
	}

	@Override
	public boolean hexists(String key, String field) {
		boolean value = true;
		try{
			jedis = getJedisCluster();
			 value = jedis.hexists(key, field);
		}catch(Exception e){
			e.printStackTrace();
		}
		return value;
	}

	@Override
	public boolean hincrBy(String key, String field, Long value) {
		boolean result = true;
		try{
			jedis = getJedisCluster();
			value = jedis.hincrBy(key, field, value);
		}catch(Exception e){
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public Long zadd(String key, double score, String member) {
		try{
			jedis = getJedisCluster();
			return jedis.zadd(key, score, member);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Long sadd(String key, String member) {
		try{
			jedis = getJedisCluster();
			return jedis.sadd(key, member);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Set<String> smembers(String key) {
		return jedis.smembers(key);
	}

	@Override
	public Set<String> sinter(String... keys) {
		return jedis.sinter(keys);
	}

	@Override
	public Double zincress(String key, double score, String member) {
		try{
			jedis = getJedisCluster();
			return jedis.zincrby(key, score, member);
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public Set<Tuple> zrevrangeWithScorese(String key, long start, long end) {
		return jedis.zrevrangeWithScores(key, start, end);
	}

	@Override
	public Double zincrby(String key, double score, String member) {
		return jedis.zincrby(key, score, member);
	}

	@Override
	public Long rpush(String key, String value) {
		return jedis.rpushx(key, value);
	}

	@Override
	public List<String> sort(String key, int start, int count) {
		SortingParams sortingParams = new SortingParams();
		sortingParams.alpha();
		sortingParams.desc();
		// sortingParams.asc();
		sortingParams.limit(start, count);
		return jedis.sort(key, sortingParams);
	}

	@Override
	public Long publish(String channel, String message) {
		return jedis.publish(channel, message);
	}

	@Override
	public Long ttl(String key) {
		return jedis.ttl(key);
	}

	@Override
	public void del(String key) {
		jedis.del(key);
	}

	@Override
	public Long smove(String srckey, String dstkey, String member) {
		return jedis.smove(srckey, dstkey, member);
	}

	@Override
	public Long scard(String key) {
		return jedis.scard(key);
	}

	@Override
	public List<String> srandmember(String key, int count) {
		return jedis.srandmember(key, count);
	}
	
	@Override
	public Long zrevrank(String key, String member) {
		return jedis.zrevrank(key, member);
	}

	@Override
	public long hlen(String key) {
		return jedis.hlen(key);
	}
	
}
